package com.newland.esp.service.user.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.newland.esp.common.constant.RedisKeyConstant;
import com.newland.esp.common.util.login.Md5Util;
import com.newland.esp.common.util.login.UUIDUtil;
import com.newland.esp.entity.user.AdminInfoEntity;
import com.newland.esp.mapper.user.AdminInfoMapper;
import com.newland.esp.service.user.SSOService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @param
 * @author lw
 * @descripe
 * @date 2021/8/14 15:44
 * @Version 1.0
 **/
@Service
public class SSOServiceImpl implements SSOService {

    private static Logger logger = LoggerFactory.getLogger(SSOServiceImpl.class);

    @Resource
    AdminInfoMapper adminInfoMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 登录认证方法返回票据 ticket
     * @param adminEntity
     * @return ticket
     */
    @Override
    public String login(AdminInfoEntity adminEntity) {

        // 判断参数的合法性
        // 去除前后空格，判断用户名和密码是否为空
        String username = adminEntity.getUserName().trim();
        String password = adminEntity.getPassword().trim();

        //前端已做检查
//        // 校验用户名
//        if (null == username || "".equals(username)) {
//            logger.error("用户名为空");
//            return null;
//        }
//        // 校验密码
//        if (null == password || "".equals(password)) {
//            logger.error("密码为空");
//            return null;
//        }
        // 通过用户名密码验证用户信息，如果用户信息唯一返回票据
        QueryWrapper wrapper = new QueryWrapper();
        // 创建查询对象
        wrapper.eq("user_name",username);
        // 根据用户名查询用户信息
        List<AdminInfoEntity> adminList = adminInfoMapper.selectList(wrapper);
        if (null == adminList || adminList.isEmpty()) {
            logger.error("该用户名不存在，用户名为： " + username);
            return null;
        }
        // 根据用户名查询到多个用户信息
        if (adminList.size() > 1) {
            logger.error("系统错误，根据用户名查询出多个用户，用户名为： " + username);
            return null;
        }
        // 密码是否一致
        AdminInfoEntity a = adminList.get(0);
        if (!a.getPassword().equals(Md5Util.getMd5WithSalt(password, a.getEcSalt()))) {
            logger.error("密码输入错误，用户名为： " + username);
            return null;
        }
        Short status = a.getStatus();
        if(status == 1){
            logger.error("未设置为可用，用户名为： " + username);
            return null;
        }
        // 用户名和密码一致，登录成功返回票据信息
        // 生成票据信息存入 redis，页面借助 cookie 存储票据的 key
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        String ticket = UUIDUtil.getUUID();
        // 设置 30 分钟的失效时间
        valueOperations.set(RedisKeyConstant.USER_TICKET +":"+ticket,
                JSONObject.toJSONString(adminList.get(0)),30, TimeUnit.MINUTES);
        // 返回票据信息
        return ticket;
    }

    /**
     * 验证票据 ticket 返回用户信息
     * @param ticket
     * @return AdminEntity
     */
    @Override
    public AdminInfoEntity validate(String ticket) {
        if (null == ticket || ticket.length() <= 0) {
            logger.error("票据信息不存在");
            return null;
        }
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        String adminJson = valueOperations.get(RedisKeyConstant.USER_TICKET +":"+ ticket);
        if (null == adminJson || adminJson.length() <= 0) {
            logger.error("票据信息无对应的用户信息");
            return null;
        }
        return JSONObject.parseObject(adminJson, AdminInfoEntity.class);
    }

    /**
     * 用户退出
     * @param ticket
     */
    @Override
    public Boolean logout(String ticket) {
        return redisTemplate.delete(RedisKeyConstant.USER_TICKET + ":" + ticket);
    }
}
